home *** CD-ROM | disk | FTP | other *** search
/ Your Choice 3 / Your Choice Software Collection 3.iso / prgmming / swag08 / sorting.swg < prev    next >
Text File  |  1994-09-22  |  24KB  |  1 lines

  1. SWAGOLX.EXE (c) 1993 GDSOFT  ALL RIGHTS RESERVED 00003                                                                           1      08-24-9413:58ALL                      LUIS MEZQUITA            Sort an Array of Record  SWAG9408    ─C½≡    18     S   {π TB>> I am having a bit of difficulty figuring out how toπ TB>> sort an array of records by numerical or alphabetical order.π TB>> Here's an example of my record set up:ππ        This a 'small' example of record quicksort.π}ππProgram SortArrayOfRec;ππuses  Crt;ππtypeππ Str34=string[34];ππ Rec=Recordπ      Name:Str34;π      Number1,π      Number2 : LongInt;π     end;ππtype CmpMinFunc=Function(var r1,r2:Rec):boolean;ππvarππ RecArray:array[1..1400] of Rec;ππ{ Compare functions }ππFunction Name(var r1,r2:Rec):boolean; far;πbeginπ Name:=r1.Name<r2.Name;πend;ππFunction Number1(var r1,r2:Rec):boolean; far;πbeginπ Number1:=r1.Number1<r2.Number1;πend;ππFunction Number2(var r1,r2:Rec):boolean; far;πbeginπ Number2:=r1.Number2<r2.Number2;πend;ππ{ QuickSort method }ππProcedure Sort(t,b:integer; Cmp:CmpMinFunc);ππProcedure QuickSort(l,r:integer);πvar i,j:integer; x,y:Rec;πbeginπ i:=l;π j:=r;π x:=RecArray[(l+r) div 2];π repeatπ  while Cmp(RecArray[i],x) do inc(i);π  while Cmp(x,RecArray[j]) do dec(j);π  if i<=jπ  then beginπ        y:=RecArray[i];π        RecArray[i]:=RecArray[j];π        RecArray[j]:=y;π        inc(i);π        dec(j);π       end;π until i>j;π if l<j then QuickSort(l,j);π if i<r then QuickSort(i,r);πend;ππbegin                                   { Procedure Sort }π QuickSort(t,b);πend;ππ{ Demo procedures }ππProcedure List(s:string);πvar n:byte;πbeginπ WriteLn(s);π for n:=1 to 9 doπ  with RecArray[n] doπ   WriteLn(n,'     ',Name,Number1:6,Number2:6);π WriteLn;π n:=Ord(ReadKey);πend;ππvar   n:byte;ππbeginπ ClrScr;π Randomize;π for n:=1 to 9 do                       { Fill RecArray with ... }π  with RecArray[n] do                   { random datas }π   beginπ    Name:=Chr(65+Random(25));π    Number1:=Random(65535);π    Number2:=Random(65535);π   end;π List('Datas');ππ Sort(1,9,Name);                        { Sort on Name }π List('Sort on Name');π Sort(1,9,Number1);                     { Sort on Number1 }π List('Sort on Number1');π Sort(1,9,Number2);                     { Sort on Number2 }π List('Sort on Number2');πend.π                                                                                                                          2      08-24-9413:58ALL                      CHRISTIAN TIBERG         Alphabetical Order       SWAG9408        ∙─z    16     S   π{ This unit will sort ANY type of data into ANY type of order. As an addedπbonus, there are a routine to search through a sorted list of ANY type...πCredits go to Björn Felten for his QSort unit, which inspired me to write thisπroutine }ππUnit SortSrch;ππinterfaceππTypeπ    CompFunc = Function(Item1, Item2: Integer): Integer;π    SwapProc = Procedure(Item1, Item2: Integer);π    CompOneFunc = Function(Item: Integer): Integer;ππProcedure QuickSort(First, Last: Integer; Comp: CompFunc; Swap: SwapProc);πFunction BinarySearch(First, Last: Integer; CompOne: CompOneFunc): Integer;ππimplementationππProcedure Partition(First, Last: Integer; Var SplitIndex: Integer;π          Comp: CompFunc; Swap: SwapProc);ππ  Varπ    Up, Down, Middle: Integer;ππ  Beginπ    Middle := ((Last - First) DIV 2 ) + First;π    Up := First;π    Down := Last;π    Repeatπ      While (Comp(Up, Middle) <= 0) And (Up < Last) Do Inc(Up);π      While (Comp(Down, Middle) > 0) And (Down > First) Do Dec(Down);π      If Up < Down Thenπ         Swap(Up, Down);π    Until Up >= Down;π    SplitIndex := Down;π    Swap(Middle, SplitIndex);π  End;ππProcedure QuickSort(First, Last: Integer; Comp: CompFunc; Swap: SwapProc);ππ  Varπ    SplitIndex: Integer;ππ  Beginπ    If First < Last Thenπ      Beginπ        Partition(First, Last, SplitIndex, Comp, Swap);π        QuickSort(First, SplitIndex - 1, Comp, Swap);π        QuickSort(SplitIndex + 1, Last, Comp, Swap);π      End;π  End;ππFunction BinarySearch(First, Last: Integer; CompOne: CompOneFunc): Integer;ππ  Varπ    Middle, Jfr: Integer;ππ  Beginπ    Repeatπ      Middle := ((Last - First) DIV 2 ) + First;π      Jfr := CompOne(Middle);π      If Jfr = 0 Thenπ        Beginπ          BinarySearch := Middle;π          Exit;π        Endπ      Else If Jfr > 0 Thenπ        First := Middleπ      Elseπ        Last := Middle;π    Until First = Last;π    BinarySearch := -1;π  End;ππend.π                3      08-24-9417:53ALL                      BRAD WILLIAMS            TV Sorting unit          SWAG9408    óWG╖    150    S   {*******************************************************************}π{                                                                   }π{     WVS Software Company                                          }π{     Turbo Pascal Sorting Unit for TCollections                    }π{     Usage Fee: None, public domain                                }π{     Version: 1.0                                                  }π{     Release Date: 6/27/93                                         }π{                                                                   }π{     Programmer: Brad Williams                                     }π{     E-mail    : bwilliams@marvin.ag.uidaho.edu                    }π{     US Mail   : 1008 E. 7th                                       }π{                 Moscow, Idaho 83843                               }π{                                                                   }π{*******************************************************************}π{                                                                   }π{  This unit contains objects for performing various types of       }π{  sorts.  To use any of the sorting methods, simply pass them a    }π{  collection and a compare or test function.  You can write your   }π{  programs to accept a TSortProcedure/TSearchFunction as a         }π{  parameter to any function or procedure and use whichever type    }π{  of sort/search you require at that point in your program.  The   }π{  search and sort methods accept pointers to compare and test      }π{  functions so that the same functions can be used for iterative   }π{  procedures/functions in a TSortedCollection.                     }π{                                                                   }π{*******************************************************************}πUNIT TVSorts;π{****************************************************************************}π                                 INTERFACEπ{****************************************************************************}πUSES Objects;ππTYPEπ  TCompareFunction = FUNCTION (Item1, Item2 : Pointer) : Integer;π    { A TCompareFunction must return:   }π    {   1  if the Item1 > Item2         }π    {   0  if the Item1 = Item2         }π    {  -1  if the Item1 < Item2         }ππ  TSortProcedure = PROCEDURE  (ACollection : PCollection;π                               Compare : TCompareFunction);ππ  { Sort Procedures }πPROCEDURE BinaryInsertionSort (ACollection : PCollection;π                               Compare : TCompareFunction);πPROCEDURE BubbleSort (ACollection : PCollection; Compare : TCompareFunction);πPROCEDURE CombSort   (ACollection : PCollection; Compare : TCompareFunction);πPROCEDURE HeapSort   (ACollection : PCollection; Compare : TCompareFunction);πPROCEDURE QuickSort  (ACollection : PCollection; Compare : TCompareFunction);πPROCEDURE QuickSortNonRecursive (ACollection : PCollection;π                                 Compare : TCompareFunction);πPROCEDURE ShakerSort (ACollection : PCollection; Compare : TCompareFunction);πPROCEDURE ShellSort  (ACollection : PCollection; Compare : TCompareFunction);πPROCEDURE StraightInsertionSort (ACollection : PCollection;π                                 Compare : TCompareFunction);πPROCEDURE StraightSelectionSort (ACollection : PCollection;π                                 Compare : TCompareFunction);πPROCEDURE TreeSort (ACollection : PCollection; Compare : TCompareFunction);πππ  { Compare Procedures - Must write your own Compare for pointer variables. }π  { This allows one sort routine to be used on any array.                   }πFUNCTION  CompareChars    (Item1, Item2 : Pointer) : Integer; FAR;πFUNCTION  CompareInts     (Item1, Item2 : Pointer) : Integer; FAR;πFUNCTION  CompareLongInts (Item1, Item2 : Pointer) : Integer; FAR;πFUNCTION  CompareReals    (Item1, Item2 : Pointer) : Integer; FAR;πFUNCTION  CompareStrs     (Item1, Item2 : Pointer) : Integer; FAR;ππ{****************************************************************************}π                               IMPLEMENTATIONπ{****************************************************************************}π{                                                                            }π{                      Local Procedures and Functions                        }π{                                                                            }π{****************************************************************************}πPROCEDURE Swap (ACollection : PCollection; A, B : Integer);πVAR Item : Pointer;πBEGINπ  Item := ACollection^.At(A);π  ACollection^.AtPut(A,ACollection^.At(B));π  ACollection^.AtPut(B,Item);πEND;π{****************************************************************************}π{                                                                            }π{                      Global Procedures and Functions                       }π{                                                                            }π{****************************************************************************}πPROCEDURE BinaryInsertionSort (ACollection : PCollection;π                               Compare : TCompareFunction);πVAR i, j, Middle, Left, Right : LongInt;πBEGINπ  FOR i := 0 TO (ACollection^.Count - 1) DOπ      BEGINπ        Left := 0;π        Right := i;π        WHILE Left < Right DOπ          BEGINπ            Middle := (Left + Right) DIV 2;π            WITH ACollection^ DOπ              IF Compare(At(Middle),At(i)) < 1π                 THEN Left := Middle + 1π                 ELSE Right := Middle;π          END;π        FOR j := i DOWNTO (Right + 1) DOπ            Swap(ACollection,j,j-1);π      END;πEND;π{****************************************************************************}πPROCEDURE BubbleSort (ACollection : PCollection; Compare : TCompareFunction);πVAR i, j : Integer;πBEGINπ  WITH ACollection^ DOπ    FOR i := 1 TO (Count - 1) DOπ        FOR j := (Count - 1) DOWNTO i DOπ        IF Compare(At(j-1),At(j)) = 1π           THEN Swap(ACollection,j,j-1);πEND;π{****************************************************************************}πPROCEDURE CombSort (ACollection : PCollection; Compare : TCompareFunction);π  { The combsort is an optimised version of the bubble sort. It uses a }π  { decreasing gap in order to compare values of more than one element }π  { apart.  By decreasing the gap the array is gradually "combed" into }π  { order ... like combing your hair. First you get rid of the large   }π  { tangles, then the smaller ones ...                                 }π  {                                                                    }π  { There are a few particular things about the combsort. Firstly, the }π  { optimal shrink factor is 1.3 (worked out through a process of      }π  { exhaustion by the guys at BYTE magazine). Secondly, by never       }π  { having a gap of 9 or 10, but always using 11, the sort is faster.  }π  {                                                                    }π  { This sort approximates an n log n sort - it's faster than any      }π  { other sort I've seen except the quicksort (and it beats that too   }π  { sometimes ... have you ever seen a quicksort become an (n-1)^2     }π  { sort ... ?). The combsort does not slow down under *any*           }π  { circumstances. In fact, on partially sorted lists (including       }π  { *reverse* sorted lists) it speeds up.                              }π  {                                                                    }π  { More information in the April 1991 BYTE magazine.                  }πCONST ShrinkFactor = 1.3;πVAR Gap, i   : LongInt;π    Finished : Boolean;πBEGINπ  Gap := Round((ACollection^.Count-1)/ShrinkFactor);π  WITH ACollection^ DOπ    REPEATπ      Finished := TRUE;π      Gap := Trunc(Gap/ShrinkFactor);π      IF Gap < 1π         THEN Gap := 1π         ELSE IF ((Gap = 9) OR (Gap = 10))π                 THEN Gap := 11;π      FOR i := 0 TO ((Count - 1) - Gap) DOπ          IF Compare(At(i),At(i+Gap)) = 1π             THEN BEGINπ                    Swap(ACollection,i,i+gap);π                    Finished := False;π                  END;π  UNTIL ((Gap = 1) AND Finished);πEND;π{****************************************************************************}πPROCEDURE HeapSort (ACollection : PCollection; Compare : TCompareFunction);π  { Performs best when items are in inverse order. }πVAR L, R : LongInt;π    X : Pointer;π    {*****************************************}π    PROCEDURE Sift;π    VAR i, j : LongInt;π        Label 13;π    BEGINπ      i := L;π      j := 2 * i;π      X := ACollection^.At(i);π      WITH ACollection^ DOπ        WHILE j <= R DOπ          BEGINπ            IF j < Rπ               THEN IF Compare(At(j),At(j+1)) = -1π                       THEN Inc(j);π            IF Compare(X,At(j)) >= 0π               THEN GoTo 13;π            AtPut(i,At(j));π            i := j;π            j := 2 * i;π          END;π      13: ACollection^.AtPut(i,X);π    END;π    {*****************************************}πBEGINπ  L := ((ACollection^.Count - 1) DIV 2) + 1;π  R := ACollection^.Count - 1;π  WHILE L > 0 DOπ    BEGINπ      Dec(L);π      Sift;π    END;π  WHILE R > 0 DOπ    BEGINπ      X := ACollection^.At(1);π      Swap(ACollection,0,R);π      Dec(R);π      Sift;π    END;πEND;π{****************************************************************************}πPROCEDURE QuickSort (ACollection : PCollection; Compare : TCompareFunction);π  {****************************************************************}π  PROCEDURE Sort (Left, Right : LongInt);π  VAR i, j  : LongInt;π      X : Pointer;π  BEGINπ    WITH ACollection^ DOπ      BEGINπ        i := Left;π        j := Right;π        X := At((Left + Right) DIV 2);π        REPEATπ          WHILE Compare(At(i),X) = -1 DO Inc(i);π          WHILE Compare(X,At(j)) = -1 DO Dec(j);π          IF i <= jπ             THEN BEGINπ                    Swap(ACollection,i,j);π                    Inc(i);π                    Dec(j)π                END;π        UNTIL i > j;π        IF Left < jπ           THEN Sort(Left,j);π        IF i < Rightπ           THEN Sort(i,Right)π      END;π  END;π  {****************************************************************}πBEGINπ  Sort(0,ACollection^.Count-1);πEND;π{****************************************************************************}πPROCEDURE QuickSortNonRecursive (ACollection : PCollection;π                                 Compare : TCompareFunction);πCONST m = 12;πVAR i, j, L, R : LongInt;π    x : Pointer;π    s : 0..m;π    Stack : ARRAY[1..m] OF RECORDπ                             l, r : LongInt;π                           END;πBEGINπ  s := 1;π  Stack[1].l := 0;π  Stack[1].r := ACollection^.Count - 1;π  WITH ACollection^ DOπ    REPEATπ      L := Stack[s].l;π      R := Stack[s].r;π      Dec(S);π      REPEATπ        i := L;π        j := R;π        x := At((L + R) DIV 2);π        REPEATπ          WHILE Compare(x,At(i)) =  1 DO Inc(i);π          WHILE Compare(x,At(j)) = -1 DO Dec(j);π          IF i <= jπ             THEN BEGINπ                    Swap(ACollection,i,j);π                    Inc(i);π                    Dec(j);π                  END;π        UNTIL i > j;π        IF i < Rπ           THEN BEGINπ                  Inc(s);π                  Stack[s].l := i;π                  Stack[s].r := R;π                END;π        R := j;π      UNTIL L >= R;π    UNTIL s = 0;πEND;π{****************************************************************************}πPROCEDURE ShakerSort (ACollection : PCollection; Compare : TCompareFunction);π  { Works for any array and any index range. }πVAR j, k, Left, Right : LongInt;πBEGINπ  Left := 1;π  Right := (ACollection^.Count - 1);π  k := Right;π  WITH ACollection^ DOπ    REPEATπ      FOR j := Right DOWNTO Left DOπ          IF Compare(At(j-1),At(j)) = 1π             THEN BEGINπ                    Swap(ACollection,j,j-1);π                    k := j;π                  END;π      Left := k + 1;π      FOR j := Left TO Right DOπ          IF Compare(At(j-1),At(j)) = 1π             THEN BEGINπ                    Swap(ACollection,j,j-1);π                    k := j;π                  END;π      Right := k - 1;π    UNTIL Left > Right;πEND;π{****************************************************************************}πPROCEDURE ShellSort (ACollection : PCollection; Compare : TCompareFunction);πVAR Gap, i, j, k : LongInt;πBEGINπ  Gap := (ACollection^.Count - 1) DIV 2;π  WHILE (Gap > 0) DOπ    BEGINπ      FOR i := Gap TO (ACollection^.Count - 1) DOπ          BEGINπ            j := i - Gap;π            WHILE (j > -1) DOπ              BEGINπ                k := j + Gap;π                IF Compare(ACollection^.At(j),ACollection^.At(k)) < 1π                   THEN j := 0π                   ELSE Swap(ACollection,j,k);π                Dec(j,Gap);π              END;π          END;π      Gap := Gap DIV 2;π    END;πEND;π{****************************************************************************}πPROCEDURE StraightInsertionSort (ACollection : PCollection;π                                 Compare : TCompareFunction);πVAR i, j : LongInt;π    X : Pointer;πBEGINπ  WITH ACollection^ DOπ    FOR i := 0 TO (Count - 1) DOπ      BEGINπ        X := At(i);π        j := i;π        WHILE (j > 0) AND (Compare(X,At(j-1)) = -1) DOπ          BEGINπ            AtPut(j,At(j-1));π            Dec(j);π          END;π        AtPut(j,X);π      END;πEND;π{****************************************************************************}πPROCEDURE StraightSelectionSort (ACollection : PCollection;π                                 Compare : TCompareFunction);πVAR i, j, k  : LongInt;πBEGINπ  FOR i := 0 TO (ACollection^.Count - 1) DOπ      BEGINπ        k := i;π        FOR j := (i + 1) TO (ACollection^.Count - 1) DOπ            IF Compare(ACollection^.At(j),ACollection^.At(k)) = -1π               THEN k := j;π        Swap(ACollection,i,k);π      END;πEND;π{****************************************************************************}πPROCEDURE TreeSort (ACollection : PCollection; Compare : TCompareFunction);π{after D.Cooke, A.H.Craven, G.M.Clarke: Statistical Computingπ in Pascal, Publisher: Edward Arnold, London 1985 ISBN 0-7131-3545-X }πTYPE PNode    = ^Node;π     Node = RECORDπ              Value : Pointer;π              Left  : PNode;π              Right : PNode;π            END;πVAR  Add, Top : PNode;π     i    : LongInt;π    {***********************************************************}π    PROCEDURE MakeTree (VAR Node : PNode);π    BEGINπ      IF Node = NILπ         THEN Node := Addπ         ELSE IF Compare(Add^.Value,Node^.Value) = 1π                 THEN MakeTree(Node^.Right)π                 ELSE MakeTree(Node^.Left);π    END;π    {**********************************************************}π     PROCEDURE StripTree (Node : PNode);π     BEGINπ       IF Node <> NILπ          THEN BEGINπ                 StripTree(Node^.Left);π                 ACollection^.AtPut(i,Node^.Value);π                 Inc(i);π                 StripTree(Node^.Right)π               END;π     END;π    {**********************************************************}πBEGINπ  Top := NIL;π  FOR i := 0 TO (ACollection^.Count - 1) DOπ    BEGINπ      New(Add);π      Add^.Value := ACollection^.At(i);π      Add^.Left  := NIL;π      Add^.Right := NIL;π      MakeTree(Top)π    END;π    i := 0;π    StripTree(Top)πEND;π{****************************************************************************}π{                                                                            }π{                            Compare Procedures                              }π{                                                                            }π{****************************************************************************}πFUNCTION CompareChars (Item1, Item2 : Pointer) : Integer;πBEGINπ  IF Char(Item1^) < Char(Item2^)π     THEN CompareChars := -1π     ELSE CompareChars := Ord(Char(Item1^) <> Char(Item2^));πEND;π{*****************************************************************************}πFUNCTION CompareInts (Item1, Item2 : Pointer) : Integer;πBEGINπ  IF Integer(Item1^) < Integer(Item2^)π     THEN CompareInts := -1π     ELSE CompareInts := Ord(Integer(Item1^) <> Integer(Item2^));πEND;π{*****************************************************************************}πFUNCTION CompareLongInts (Item1, Item2 : Pointer) : Integer;πBEGINπ  IF LongInt(Item1^) < LongInt(Item2^)π     THEN CompareLongInts := -1π     ELSE CompareLongInts := Ord(LongInt(Item1^) <> LongInt(Item2^));πEND;π{*****************************************************************************}πFUNCTION CompareReals (Item1, Item2 : Pointer) : Integer;πBEGINπ  IF Real(Item1^) < Real(Item2^)π     THEN CompareReals := -1π     ELSE CompareReals := Ord(Real(Item1^) <> Real(Item2^));πEND;π{*****************************************************************************}πFUNCTION CompareStrs (Item1, Item2 : Pointer) : Integer;πBEGINπ  IF String(Item1^) < String(Item2^)π     THEN CompareStrs := -1π     ELSE CompareStrs := Ord(String(Item1^) <> String(Item2^));πEND;π{*****************************************************************************}πBEGINπEND.ππ{ -----------------------------------  DEMO PROGRAM ---------------------}ππPROGRAM Test;πUSES Crt, Objects, TVSorts;ππCONSTπ  MaxCollectionSize = 10;ππVAR C : TCollection;π    i, j, k : Integer;π    Ch : ^Char;ππBEGINπ  Randomize;π  FOR i := 1 TO 11 DOπ    BEGINπ        { initialize collection and load with data in reverse order }π      C.Init(MaxCollectionSize,1);π      FOR j := MaxCollectionSize DOWNTO 0 DOπ          BEGINπ            k := Random(255);π            WHILE (k < 65) OR (k > 90) DO k := Random(255);π            New(Ch);π            Ch^ := Char(k);π            C.AtInsert(0,Ch);π          END;π        { display unsorted data }π      ClrScr;π      CASE i OFπ        1 : WriteLn('Binary Insertion Sort');π        2 : WriteLn('Bubble Sort');π        3 : WriteLn('Comb Sort');π        4 : WriteLn('Heap Sort');π        5 : WriteLn('Quick Sort');π        6 : WriteLn('Non-recursive Quick Sort');π        7 : WriteLn('Shaker Sort');π        8 : WriteLn('Shell Sort');π        9 : WriteLn('Straight Insertion Sort');π       10 : WriteLn('Straight Selection Sort');π       11 : WriteLn('Tree Sort');π      END;π      FOR j := 0 TO (C.Count - 1) DO Write(Char(C.At(j)^):2);π        { sort data }π      CASE i OFπ        1 : BinaryInsertionSort(@C,CompareChars);π        2 : BubbleSort(@C,CompareChars);π        3 : CombSort(@C,CompareChars);π        4 : HeapSort(@C,CompareChars);π        5 : QuickSort(@C,CompareChars);π        6 : QuickSortNonRecursive(@C,CompareChars);π        7 : ShakerSort(@C,CompareChars);π        8 : ShellSort(@C,CompareChars);π        9 : StraightInsertionSort(@C,CompareChars);π       10 : StraightSelectionSort(@C,CompareChars);π       11 : TreeSort(@C,CompareChars);π      END;π        { display sorted data }π      WriteLn;π      FOR j := 0 TO (C.Count - 1) DO Write(Char(C.At(j)^):2);π      ReadLn;π        { clear of collection }π    END;πEND.